package com.rq.rvlibrary;

import android.content.Context;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.NotSerializableException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import static com.rq.rvlibrary.BaseViewHolder.TAG_POSITION;

public class BaseAdapter<DATA, VH extends BaseViewHolder> extends
        RecyclerView.Adapter<VH> implements
        AdapterHolderControllerHelper {

    public static void setDebugLog(boolean show) {
        //LOG.SHOW_DEBUG = show;
    }

    protected SparseArray<Class<? extends BaseViewHolder>> multipleHolder;
    Context mContext;
    Class<VH> mHolder;//内部不要直接引用 避免出错  ->  mainHolder()
    private int itemId;
    private Object mObject;
    private List<DATA> showData = new ArrayList<>();
    private SparseArray<Class<? extends BaseViewHolder>> headType = new SparseArray<>();//顶部视图处理器类型
    private SparseArray<Object> headViewData = new SparseArray<>();//顶部视图数据
    private SparseIntArray headViewResId = new SparseIntArray();
    private SparseArray<Class<? extends BaseViewHolder>> footType = new SparseArray<>();//底部视图处理器类型
    private SparseArray<Object> footViewData = new SparseArray<>();//底部视图数据
    private SparseIntArray footViewResId = new SparseIntArray();
    private ActionPasser mActionPasser;
    private HashMap<Class, OnClickMaker> clicks = new HashMap<>();
    private HashMap<Class, OnPressMaker> press = new HashMap<>();
    //  private OnAttachedToBottomListener mOnAttachedToBottomListener;
    private Map<String, Object> contentCash = new HashMap<>();
    RecyclerView recyclerView;

    private void setContext(Context context) {
        this.mContext = context;
    }

    /**
     * 默认 EasyViewHolder.class
     */
    public BaseAdapter(Context context, @LayoutRes int itemLayoutId) {
        this.mContext = context;
        this.itemId = itemLayoutId;
        this.mObject = null;
        this.init();
    }

    /**
     * 给快速实现提供的可重写初始化方法
     */
    protected void init() {
    }

    protected final Context getContext() {
        return mContext;
    }

    public BaseAdapter(Context context, @LayoutRes int itemLayoutId, Class baseViewHolderClass) {
        this(context, itemLayoutId, baseViewHolderClass, null);
    }

    /**
     * 单布局类型  只要一种子View setData 数据条数大于 0  才会显示
     *
     * @param itemLayoutId 对 BrandHolder 的描述，必须与 BaseViewHolder 使用保持一致
     */
    public BaseAdapter(Context context, @LayoutRes int itemLayoutId, Class baseViewHolderClass,
                       Object obj) {
        if (context == null || baseViewHolderClass == null || itemLayoutId == 0) {
            //LOG.e("BaseAdapter", "85:" + (context == null));
            //LOG.e("BaseAdapter", "86:" + (baseViewHolderClass == null));
            //LOG.e("BaseAdapter", "87:" + (itemLayoutId == 0));
            //LOG.showUserWhere("BaseAdapter");
            throw new AdapterUseException("BaseAdapter.使用三参数构造函数 值不能为空1");
        }
        if (baseViewHolderClass.isAssignableFrom(BaseViewHolder.class)) {
            throw new AdapterUseException("BaseAdapter 传入ViewHolder 需要继承 com.rq.rvlibrary.BaseViewHolder");
        }
        this.mContext = context;
        this.mHolder = baseViewHolderClass;
        this.itemId = itemLayoutId;
        this.mObject = obj;
        this.init();
    }

    public BaseAdapter(Context context, NestingBuilder builder) {
        this.mContext = context;
        this.mHolder = builder.getHolderClazz();
        this.itemId = builder.getOutLayoutId();
        this.mObject = builder;
        this.init();
    }


    @Override
    public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
        this.recyclerView = recyclerView;
    }

    /**
     * 不建议使用，每创建一个ViewHolder会动用两次反射{@link BaseAdapter#getViewHolderByClass(Class, int, ViewGroup, int)}，
     * 布局ID通过重写{@link BaseViewHolder#inflateLayoutId()}指定
     */
    @Deprecated
    public BaseAdapter(Context context, Class<VH> baseViewHolderClass, Object obj) {
        if (context == null || baseViewHolderClass == null) {
            throw new AdapterUseException("BaseAdapter.使用三参数构造函数 值不能为空2");
        }
        setContext(context);
        this.mHolder = baseViewHolderClass;
        this.mObject = obj;
    }

    /**
     * 无序布局   子视图有多种类型
     * 不固定位置
     *
     * @param maps key  对 BrandHolder 的描述，value key布局对应的 BaseViewHolder.class，必须与 BaseViewHolder 使用保持一致
     */
    public BaseAdapter(Context context, @NonNull SparseArray<Class<? extends BaseViewHolder>> maps,
                       Object... innerClassContext) {
        this.mContext = context;
        this.multipleHolder = maps;
        if (innerClassContext != null && innerClassContext.length > 0) {
            this.mObject = innerClassContext[0];
        }
        getMultipleHolderType(null, 0);//进行检测
    }

    /**
     * 追加型布局
     */
    //  public BaseAdapter(Context context) {
    //    this.mContext = context;
    //  }
    public void changeItemView(int viewLayout, boolean refuse) {
        this.itemId = viewLayout;
        if (refuse) {
            notifyChange();
        }
    }

    boolean showEmpty = false;//展示空视图
    private final static int TYPE_EMPTY = 100865;
    SparseArray<Object> pass;

    /**
     * {@link BaseAdapter#setPassData2Key(int, Object)}
     */
    @Deprecated
    public void setPassData(Object... passData) {
        if (passData != null && passData.length > 0) {
            if (pass == null) {
                pass = new SparseArray<>();
            }
            for (int i = 0; i < passData.length; i++) {
                pass.put(i, passData[i]);
            }
        }
    }

    public void setPassData2Key(int key, Object obj) {
        if (obj != null) {
            if (pass == null) {
                pass = new SparseArray<>();
            }
            //LOG.e("BaseAdapter", "setPassData2Key.167:" + this);
            //LOG.e("BaseAdapter", pass + "setPassData2Key." + key + ":" + obj);
            pass.put(key, obj);
        }
    }

    public SparseArray<Object> getPass() {
        return pass;
    }

    public Object getNullablePass(int position) {
        if (pass != null) {
            Object obj = pass.get(position);
            //LOG.e("BaseAdapter", "getNullablePass.177:" + this);
            //LOG.e("BaseAdapter", pass + "getNullablePass." + position + ":" + obj);
            return obj;
        }
        return null;
    }

    private boolean usingDiffUtil = false;
    private boolean usingHandler = false;
    private RQDiffUtil mRQDiffUtil;

    /**
     * 开启数据对比,开启后数据变化时只会更新对应ViewHolder ,数据需要实现 Compare
     * {@link Compare}
     *
     * @param use 是否在子线程中进行数据对比,默认不需要
     */
    public void openDiffUtil(boolean use) {
        this.usingHandler = use;
        this.usingDiffUtil = true;
    }

    /**
     * 开启数据对比,开启后数据变化时只会更新对应ViewHolder ,数据需要实现 Compare
     * {@link Compare}
     */
    public void openDiffUtil() {
        this.openDiffUtil(false);
    }

    /**
     * 直接刷新视图，数据为空将置空列表
     *
     * @param dataList 填充数据
     */
    public synchronized void setData(List dataList) {
        if (usingDiffUtil) {
            if (dataList != null) {
                this.showData = dataList;
            }
            if (mRQDiffUtil == null) {
                mRQDiffUtil = new RQDiffUtil(dataList);
                this.notifyChange();
            } else {
                mRQDiffUtil.setNewData(dataList, this);
            }
        } else {
            this.showData.clear();
            if (dataList != null) {
                this.showData = dataList;
            }
            if (this.showRule != null) {
                //LOG.d("BaseAdapter", "setData.167:" + showRule + "<");
                display(this.showRule, dataList);
                return;
            }
            this.showEmpty = emptyLayout() != 0 && (dataList == null || dataList.size() == 0);
            this.notifyChange();
        }
    }


    @Override
    public List getData() {
        return this.showData;
    }

    public List getOriginData() {
        if (originData == null || originData.size() == 0) {
            return showData;
        } else {
            return originData;
        }
    }

    public void notifyDataChange() {
        try {
            notifyDataSetChanged();
        } catch (Exception e) {

        }
    }

    @Override
    public void notifyChange() {
        //LOG.showUserWhere("notifyChange");
        try {
            notifyDataSetChanged();
        } catch (Exception e) {

        }
    }

    protected int emptyLayout() {
        return this.emptyLayout;
    }

    public void addData(List dataList) {
        if (dataList == null) {
            return;
        }
        LOG.e("BaseAdapter", "addData.304:" + dataList.size());
        LOG.e("BaseAdapter", "addData.305:" + getData().size());
        List old = deepCopy(getData());
        old.addAll(dataList);
        LOG.e("BaseAdapter", "addData.308:" + old.size());
        setData(old);
    }

    public void addData(int position, List dataList) {
        if (dataList == null) {
            return;
        }
        List old = deepCopy(getData());
        if (position < old.size()) {
            old.addAll(position, dataList);
        } else {
            old.addAll(dataList);
        }
        setData(old);
    }

    public void addData(DATA dataList) {
        if (dataList == null) {
            return;
        }
        List old = deepCopy(getData());
        old.add(dataList);
        setData(old);
    }

    public void addData(int position, DATA dataList) {
        if (dataList == null) {
            return;
        }
        List old = deepCopy(getData());
        if (position < old.size()) {
            old.add(position, dataList);
        } else {
            old.add(dataList);
        }
        setData(old);
    }

    public DATA getDataItem(int position) {//真实下标
        if (position >= 0 && position < showData.size()) {
            return showData.get(position);
        }
        return null;
    }

    @Override
    public int getItemViewType(int position) {
        int headSize = headViewData.size();
        int footSize = footViewData.size();
        int dataSize = showData.size();

        if (isShowEmpty()) {
            return TYPE_EMPTY;
        }
        boolean isHead = position < headViewData.size();
        if (isHead) {//头部数据
            return -headSize + position;
        }
        boolean isFoot = (position >= headViewData.size() + showData.size());
        if (isFoot) { //尾部数据
            int footPosition = position - headSize - dataSize;
            return Integer.MIN_VALUE + footPosition;
        }
        if (multipleHolder != null) {
            return getMultipleHolderType(getObjectWithRealPosition(position), getCSPosition(position));
        }
        return 0;
    }

    /**
     * @param dataItem 数据内容
     * @param position 数据位置 为负数则表示为头/尾 部数据
     * @return 返回布局Id
     */
    protected int getMultipleHolderType(Object dataItem, int position) {
        throw new AdapterUseException(" 多类型布局使用错误，必须复写 getMultipleHolderType() 方法,并且不调用父类方法  ");
    }

    private Class mainHolder() {
        if (mHolder != null) {
            return mHolder;
        } else {
            return EasyViewHolder.class;
        }
    }

    @Override
    public VH onCreateViewHolder(ViewGroup parent, int viewType) {
        VH viewHolder;
        if (viewType == TYPE_EMPTY) {
            View v = LayoutInflater.from(mContext).inflate(emptyLayout(), parent, false);
            viewHolder = (VH) new EmptyViewHolder(v);
        } else if (multipleHolder != null && viewType > 0) {
            Class clazz = multipleHolder.get(viewType);
            if (clazz == null) {
                throw new AdapterUseException(" 多类型布局使用错误，multipleHolder key 为 R.layout.***   value 为 ***Holder.class  ");
            }
            viewHolder = getViewHolderByClass(clazz, viewType, parent, viewType);
        } else if (viewType < 0) {
            if (viewType >= -headViewData.size()) {
                //       viewType= - headViewData.size() + position
                int realPosition = headViewData.size() + viewType;
                final Class<?> holderRoot = headType.get(realPosition);
                //LOG.d("BaseAdapter", "onCreateViewHolder.viewType: " + viewType + "  " + holderRoot);
                viewHolder = getViewHolderByClass(holderRoot, headViewResId
                        .get(realPosition), parent, realPosition);
            } else {
                //        viewType=Integer.MIN_VALUE + position;
                int footPosition = viewType - Integer.MIN_VALUE;
                //LOG.d("BaseAdapter", "onCreateViewHolder:footPosition = " + footPosition);
                viewHolder = getViewHolderByClass(footType.get(footPosition), footViewResId
                        .get(footPosition), parent, footPosition);
            }
        } else {
            viewHolder = getViewHolderByClass(mainHolder(), this.itemId, parent, viewType);
        }
        if (viewHolder != null) {
            if (pass != null) {
                viewHolder.setPass(pass);
            }
            OnClickMaker itemOnClickMaker = clicks.get(viewHolder.getClass());
            if (itemOnClickMaker != null) {
                viewHolder.setClickInfo(itemOnClickMaker);
            }
            OnPressMaker itemOnPressMaker = press.get(viewHolder.getClass());
            if (itemOnPressMaker != null) {
                viewHolder.setPressInfo(itemOnPressMaker);
            }
            viewHolder.setContext(mContext);
            ViewGroup.LayoutParams lmp = childLayoutParams(viewHolder.itemView.getLayoutParams(), recyclerView.getWidth(), recyclerView.getHeight());
            lmp = viewHolder.getLMLayoutParams(lmp, recyclerView.getWidth(), recyclerView.getHeight());
            if (lmp != null) {
                viewHolder.itemView.setLayoutParams(lmp);
            }
            if (childLayoutParams(viewHolder.itemView, recyclerView.getWidth(), recyclerView.getHeight()) != null) {
                Map<Integer, ViewGroup.LayoutParams> p = childLayoutParams(viewHolder.itemView, recyclerView.getWidth(), recyclerView.getHeight());
                p = viewHolder.getChildLayoutParams(p, recyclerView.getWidth(), recyclerView.getHeight());
                if (p.size() > 0) {
                    for (Integer id : p.keySet()) {
                        if (viewHolder.itemView.findViewById(id) != null) {
                            viewHolder.itemView.findViewById(id).setLayoutParams(p.get(id));
                        }
                    }
                }
            }
        }
        if (viewHolder instanceof NestingViewHolder && mObject instanceof NestingBuilder) {
            ((NestingViewHolder) viewHolder).init(((NestingBuilder) mObject));
        } else if (viewHolder instanceof NestingViewHolder) {
            ((NestingViewHolder) viewHolder).init(null);
        }
        viewHolder.setRecyclerView(recyclerView);
        return viewHolder;
    }

    protected void refuseLayoutParam(int position, VH holder, Object data) {
    }


    protected Map<Integer, ViewGroup.LayoutParams> childLayoutParams(View itemView, int measuredWidth, int measuredHeight) {
        return childLayoutParams(itemView);
    }

    @Deprecated
    protected Map<Integer, ViewGroup.LayoutParams> childLayoutParams(View itemView) {
        return null;
    }

    /**
     * 统一指定子视图布局属性，优先级低于 {@link BaseViewHolder#getLMLayoutParams(ViewGroup.LayoutParams, int w, int h)}
     *
     * @param layoutParams
     * @return
     */
    protected ViewGroup.LayoutParams childLayoutParams(ViewGroup.LayoutParams layoutParams, int parentWidth, int parentHeight) {
        return childLayoutParams(layoutParams);
    }

    @Deprecated
    protected ViewGroup.LayoutParams childLayoutParams(ViewGroup.LayoutParams layoutParams) {
        return layoutParams;
    }

    private Object getMore() {
        if (mObject instanceof NestingBuilder) {
            return ((NestingBuilder) mObject).usingInnerClass;
        } else {
            return mObject;
        }
    }

    public static void setCheckLayout(boolean check) {
        checkLayout = check;
    }

    private static boolean checkLayout = false;

    /**
     * 通过反射获取Holder实例
     */
    protected VH getViewHolderByClass(@NonNull Class<?> holderRoot, @LayoutRes int resId,
                                      ViewGroup parent, int viewType) {
        String error = "";
        String holdName = "";
        if (holderRoot == null) {
            holderRoot = EasyViewHolder.class;
        }
        holdName = holderRoot.getSimpleName();
        if (EmptyViewHolder.class.getSimpleName().equals(holdName)) {
            View itemView = LayoutInflater.from(mContext).inflate(resId, parent, false);
            itemView.setTag(R.id.rv_child_layout, resId);
            return (VH) new EmptyViewHolder(itemView);
        }

        try {
            Constructor<?>[] ctors = holderRoot.getDeclaredConstructors();
            if (ctors != null && ctors.length > 0) {
                View itemView = LayoutInflater.from(mContext).inflate(resId, parent, false);
                VH holder;
                try {
                    holder = (VH) ctors[0].newInstance(itemView);
                } catch (IllegalArgumentException e) {
                    if (getMore() != null) {
                        holder = (VH) ctors[0].newInstance(getMore(), itemView);
                    } else {
                        throw e;
                    }
                }
                if (holder == null) {
                    throw new AdapterUseException(holderRoot
                            .getSimpleName() + " 获取到了一个空  Holder -_-||  --> " + viewType);
                }
                if (!(holder instanceof OnDataBinding) && checkLayout && holder
                        .inflateLayoutId() != resId && !(holder instanceof EasyViewHolder)) {
                    throw new AdapterUseException(holderRoot
                            .getSimpleName() + " 布局使用错误,请重写viewHolder.inflateLayoutId   --> " + viewType + "\n-------------该方法为了维护而写 可使用 BaseAdapter.setCheckLayout() 关闭该检查");
                }
                holder.itemView.setTag(R.id.rv_child_layout, resId);
                if (mActionPasser != null) {
                    holder.setPasser(mActionPasser);
                }
                if (holder instanceof AdapterHolderController) {
                    ((AdapterHolderController) holder).setDataPasser(this);
                }
                return holder;
            }
        } catch (InstantiationException e) {
            error = "Exception:InstantiationException";
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            error = "Exception:IllegalAccessException";
            e.printStackTrace();
        } catch (Exception e) {
            error = "Exception:e";
            e.printStackTrace();
        }
        if (error != null && error.contains("Wrong number of arguments")) {
            error = error + "\n【【【" + holderRoot
                    .getSimpleName() + ".调用类内部类ViewHolder 调用四参数构造方法 或者 重写 getMore() 内容 】】】";
        }
        String errName = holderRoot == null ? "ERROR" : holderRoot.getName();
        //LOG.showUserWhere("EasyViewHolder");
        throw new AdapterUseException(errName + " 初始化异常:" + error);
    }


    public List<Object> getItemInput() {
        List<ViewDataGetter> mViewDataGetters = new ArrayList<>();
        List<Object> res = new ArrayList<>();
        for (int i = 0; i < getDataSize(); i++) {
            if (recyclerView.findViewHolderForAdapterPosition(i) instanceof ViewDataGetter) {
                mViewDataGetters.add((ViewDataGetter) recyclerView.findViewHolderForAdapterPosition(i));
            }
        }
        if (mViewDataGetters.size() != 0) {
            for (ViewDataGetter item : mViewDataGetters) {
                res.add(item.getViewData());
            }
        }
        return res;
    }

    /**
     * @return 是否重新onBindEasyHolder
     */
    private boolean hasOverrideOnBindEasyHolder() {
        Method onBindEasyHolder = null;
        try {
            for (Method method : this.getClass().getDeclaredMethods()) {
                if ("onBindEasyHolder".equals(method.getName())) {
                    onBindEasyHolder = method;
                    break;
                }
            }
        } catch (Exception e) {
            //LOG.e("BaseAdapter", "hasOverrideOnBindEasyHolder.556:");
        }
        boolean hasOverride = onBindEasyHolder != null && onBindEasyHolder.getDeclaringClass() != BaseViewHolder.class;
        return hasOverride;
    }

    @Override
    public void onViewRecycled(@NonNull VH holder) {
        super.onViewRecycled(holder);
        if (holder instanceof ViewDataGetter) {
            //LOG.e("BaseAdapter", "onViewRecycled:" + ((ViewDataGetter) holder).getViewData());
        }
    }

    @Override
    public void onBindViewHolder(VH holder, int position) {
        try {

            if (pass != null) {
                holder.setPass(pass);
            }
            holder.itemView.setTag(TAG_POSITION, position - headViewData.size());
            if (isShowEmpty()) {
                onBindEmptyViewHolder(this, holder);
                return;
            }
            if (holder instanceof OnContentKeeper) {
                //LOG.d("onBindViewHolder", "addView");
                //LOG.d("BaseAdapter", "onBindViewHolder: " + holder.getPosition());
                useCash(holder);
                return;
            }
            Object data = getObjectWithRealPosition(position);
            if (selectRule instanceof Integer) {
                holder.needSelect(this, getCSPosition(position));
            }
            if (data instanceof OnDataBinding) {
                ((OnDataBinding) data).bindViewHolder(this, holder, position, data);
            }
            if (holder instanceof OnDataBinding) {
                ((OnDataBinding) holder).bindViewHolder(this, holder, position, data);
            }

            if (position < headViewData.size()) {
                onBindHeadHolder(this, holder, position, data);
            } else if (position >= headViewData.size() + showData.size()) {
                onBindFootHolder(this, holder, position, data);
            } else if (holder instanceof EasyViewHolder) {
                if (hasOverrideOnBindEasyHolder()) {
                    onBindEasyHolder(this, holder, position - headViewData.size(), (DATA) data);
                } else {
                    onBindMultipleHolder(this, holder, getCSPosition(position), data);
                }

            } else if (multipleHolder != null) {
                onBindMultipleHolder(this, holder, getCSPosition(position), data);
            } else if (hasOverrideOnBindEasyHolder()) {
                onBindEasyHolder(this, holder, position - headViewData.size(), (DATA) data);
            }
            holder.setData(data);
            if (holder instanceof ViewDataGetter && position < saveBeforeDelete.size()) {
                ((ViewDataGetter) holder).afterChange(saveBeforeDelete.get(position), position);
            }
            try {

                holder.fillData(this, getCSPosition(position), data);
            } catch (Exception e) {
                e.printStackTrace();
                //LOG.e("BaseAdapter", holder.getClass().getSimpleName() + ">602:" + position + ":" + getCSPosition(position) + "--》" + data);
            }
            refuseLayoutParam(position, holder, data);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private int getCSPosition(int position) {
        if (position < headViewData.size()) {
            return headViewData.size() * -1 + position;
        } else if (position >= headViewData.size() + showData.size() && headViewData.size() + showData
                .size() > 0) {
            int positionInFoot = position - headViewData.size() - showData.size();
            return Integer.MIN_VALUE + positionInFoot;
        } else {
            return position - headViewData.size();
        }
    }

    protected Object getObjectWithRealPosition(int position) {
        if (position < headViewData.size()) {
            return headViewData.get(position);
        } else if (position >= headViewData.size() + showData.size() && headViewData.size() + showData
                .size() > 0) {
            int positionInFoot = position - headViewData.size() - showData.size();
            //      Integer.MIN_VALUE + positionInFoot
            return footViewData.get(positionInFoot);
        } else {
            try {
                return showData.get(position - headViewData.size());
            } catch (Exception e) {
                return null;
            }
        }
    }

    /**
     * {@link BaseAdapter#addHeadHolder(Class, int, Object)}
     * {@link BaseAdapter#addHeadHolder(Object, Class, int, Object)}
     * {@link BaseAdapter#setHeadHolder(int, Object, Class, int, Object)}
     */
    protected void onBindHeadHolder(BaseAdapter<DATA, VH> adapter, VH holder, int position,
                                    Object data) {
    }

    /**
     * {@link BaseAdapter#addFootHolder(Class, int, Object)}
     * {@link BaseAdapter#addFootHolder(Object, Class, int, Object)}
     * {@link BaseAdapter#setFootHolder(int, Object, Class, int, Object)}
     */
    protected void onBindFootHolder(BaseAdapter<DATA, VH> adapter, VH holder, int position,
                                    Object data) {
    }

    /**
     * @param adapter
     * @param holder
     * @param position "<0" ->  头/尾部数据  ">0" -> 常规数据
     * @param data
     */
    protected void onBindMultipleHolder(BaseAdapter adapter, VH holder, int position, Object data) {
    }

    protected void onBindEmptyViewHolder(BaseAdapter adapter, VH holder) {
    }

    protected void onBindEasyHolder(BaseAdapter adapter, VH holder, int position, DATA data) {
    }

    private boolean NEED_EMPTY_SHOW = false;

    public boolean isShowEmpty() {
        return showEmpty && NEED_EMPTY_SHOW;
    }

    public void clearData() {
        if (showData != null) {
            showData.clear();
        }
        if (originData != null) {
            originData.clear();
        }
        notifyChange();
    }

    /**
     * 实际数据数量 不包含 HeadView 和 FootView 数量
     */
    public int getDataSize() {
        return showData.size();
    }

    /**
     * @see #getDataSize()
     */
    @Override
    @Deprecated
    public int getItemCount() {
        if (isShowEmpty()) {
            return 1;
        }
        int size = 0;
        if (showData != null) {
            size += showData.size();
        }
        if (headViewData != null) {
            size += headViewData.size();
        }
        if (footViewData != null) {
            size += footViewData.size();
        }
        return size;
    }

    public final int getHeadSize() {
        return headViewData.size();
    }

    public final int getFootSize() {
        return footViewData.size();
    }

    public void addFootHolder(Object object, Class<? extends BaseViewHolder> footHolder,
                              @LayoutRes int resId, Object more) {
        setFootHolder(footType.size(), object, footHolder, resId, more);
    }

    public void addFootHolder(Class<? extends BaseViewHolder> footHolder, @LayoutRes int resId,
                              Object more) {
        setFootHolder(footType.size(), null, footHolder, resId, more);
    }

    /**
     * 由于 SparseArray 的特性，add***Holder只能从前面往后面追加，要增加指定顺序需更换为HasMap
     * 需要进行替换，使用以下方法
     */
    public void setFootHolder(int position, Object object, Class<? extends BaseViewHolder> footHolder,
                              @LayoutRes int resId, Object more) {
        if (position < footType.size()) {
            footType.delete(position);
            footViewData.delete(position);
            footViewResId.delete(position);
        }
        footType.put(position, footHolder);
        footViewData.put(position, object);
        footViewResId.put(position, resId);
        this.mObject = more;
        this.notifyItemChanged(position);
    }

    public void addHeadHolder(Class<? extends BaseViewHolder> headHolder, @LayoutRes int resId,
                              Object more) {
        setHeadHolder(headType.size(), null, headHolder, resId, more);
    }

    public void addHeadHolder(Object object, Class<? extends BaseViewHolder> headHolder,
                              @LayoutRes int resId, Object more) {
        setHeadHolder(headType.size(), object, headHolder, resId, more);
    }

    /**
     * @param position   头序号，与数据序号无关
     * @param object     数据
     * @param headHolder 文件
     * @param resId      布局
     */
    public void setHeadHolder(int position, Object object, Class<? extends BaseViewHolder> headHolder,
                              @LayoutRes int resId, Object more) {
        if (position < headType.size()) {
            headType.delete(position);
            headViewData.delete(position);
            headViewResId.delete(position);
        }
        headType.put(position, headHolder);
        headViewData.put(position, object);
        headViewResId.put(position, resId);
        this.mObject = more;
        this.notifyItemChanged(position);
    }

    public void clearHeadView() {
        headType.clear();
        headViewData.clear();
        headViewResId.clear();
        notifyChange();
    }

    public void clearFootView() {
        footType.clear();
        footViewData.clear();
        footViewResId.clear();
        this.notifyChange();
    }

    /**
     * 常见交互可通过 addOnItemClickListener 方法设置
     *
     * @see #addOnItemClickListener(OnItemClickListener, int...)
     */
    @Deprecated
    public void setActionPasser(ActionPasser passer) {
        this.mActionPasser = passer;
    }

    @Override
    public void onViewDetachedFromWindow(@NonNull VH holder) {
        if (holder instanceof OnContentKeeper) {
            //LOG.e("BaseAdapter", "783:removeItem");
            setCash(holder);
        }
    }

    @Override
    public void onViewAttachedToWindow(@NonNull VH holder) {
        if (holder instanceof OnContentKeeper) {
            //LOG.e("BaseAdapter", "790:removeItem");
            useCash(holder);
        }
        //    if (holder.getAdapterPosition() == getItemCount() - 1) {
        //      onAttachedToBottom(holder.getAdapterPosition());
        //    } else if (holder.getAdapterPosition() == 0) {
        //      if (mOnAttachedToBottomListener != null) {
        //        mOnAttachedToBottomListener.onAttachedToTop();
        //      }
        //    }
    }
//    public void removeItem(Object item) {
//        //LOG.e("BaseAdapter", "Object.removeItem:in");
//        List old = BaseAdapter.deepCopy(getData());
//        old.remove(item);
//        setData(old);
//    }

    public DATA removeItem(int deletePosition) {
        List old = BaseAdapter.deepCopy(getData());
        if (deletePosition >= old.size() || deletePosition < 0) return null;
        Object r = old.remove(deletePosition);
        //LOG.e("BaseAdapter", deletePosition + ".removeItem:" + old);
        if (removeItems(deletePosition, 1)) {
            return (DATA) r;
        } else {
            return null;
        }
    }

    /**
     * 移除部分数据
     *
     * @param deleteFrom 起始数据
     * @param deleteSize 移除长度
     * @return
     */
    public synchronized boolean removeItems(int deleteFrom, int deleteSize) {
        if (getData() == null || deleteFrom >= getData().size() || deleteSize <= 0) {
            return false;
        }
        List old = BaseAdapter.deepCopy(getData());
        int oldDataSize = old.size();
        //LOG.e("BaseAdapter", "removeViewSave.before.oldDataSize:" + oldDataSize);
        //LOG.e("BaseAdapter", "removeViewSave.before.(deleteFrom + deleteSize):" + (deleteFrom + deleteSize));
        List copy = new ArrayList();
        boolean res = false;
        for (int i = 0; i < old.size(); i++) {
            if (i < deleteFrom || i >= deleteFrom + deleteSize) {
                copy.add(old.get(i));
            } else {
                res = true;
            }
        }
        int oldSize = recyclerView.getChildCount();
        removeSave(deleteFrom, deleteSize);
        setData(copy);
        //LOG.e("BaseAdapter", "removeViewSave.before:" + old.size());
        removeViewSave(deleteFrom, deleteSize, oldSize, oldDataSize);
        return res;
    }

    private void removeViewSave(int deletePosition, int deleteSize, int oldSize, int oldDataSize) {
        if (multipleHolder != null) {
            //LOG.e("BaseAdapter", "多类子项暂不支持该功能");
            return;
        }
        int deleteLength = deletePosition + deleteSize < oldDataSize ? deleteSize : (oldDataSize - deletePosition);
        int viewDeleteFrom = oldSize - getFootSize() - 1;
        for (int i = 0; i < deleteLength; i++) {
            recyclerView.removeView(recyclerView.getChildAt(viewDeleteFrom - i));
        }

    }

    public void show() {
        for (int i = 0; i < recyclerView.getChildCount(); i++) {
            //LOG.e("BaseAdapter", i + ".KeepAct:" + recyclerView.getChildAt(i).isShown());
        }
    }

    List<Object[]> saveBeforeDelete = new ArrayList<>();


    private void removeSave(int position, int deleteSize) {
        if (multipleHolder != null) {
            //LOG.e("BaseAdapter", "多类子项暂不支持该功能");
            return;
        }
        try {
            RecyclerView.ViewHolder viewHolder = recyclerView.getChildViewHolder(recyclerView.getChildAt(0));
            if (viewHolder instanceof ViewDataGetter) {
                saveBeforeDelete.clear();
                for (int i = 0; i < recyclerView.getChildCount(); i++) {
                    if (i < position || i >= position + deleteSize) {
                        saveBeforeDelete.add(((ViewDataGetter) recyclerView.getChildViewHolder(recyclerView.getChildAt(i))).beforeChange());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int getLastDataPosition() {
        return headViewData.size() + getData().size() - 1;
    }

    /**
     * 添加长按事件
     *
     * @param ids 需要绑定试图id  不填则绑定外层试图
     */
    public void addOnLongPressListener(OnItemPressListener listener, int... ids) {
        this.addOnLongPressListener(mainHolder(), listener, ids);
    }

    public void addOnLongPressListener(Class<? extends BaseViewHolder> clazz,
                                       OnItemPressListener clickListener, int... ids) {
        if (clazz != null && clickListener != null) {
            press.put(clazz, new OnPressMaker(clickListener, ids));
        }
    }

    @Deprecated
    public void setOnItemClickListener(OnItemClickListener clickListener, int... ids) {
        this.setOnItemClickListener(mainHolder(), clickListener, ids);
    }

    @Deprecated
    public void setOnItemClickListener(Class<? extends BaseViewHolder> clazz, OnItemClickListener clickListener, int... ids) {
        clicks.put(clazz, new OnClickMaker(clickListener, ids));
    }


    public void addOnItemClickListener(OnItemClickListener clickListener) {
        this.addOnItemClickListener(mainHolder(), clickListener);
    }

    /**
     * 添加点击事件
     *
     * @param ids 需要绑定试图id  不填则绑定外层试图
     */
    public void addOnItemClickListener(OnItemClickListener clickListener, int... ids) {
        this.addOnItemClickListener(mainHolder(), clickListener, ids);
    }

    /**
     * 优先级低于 {@link OnInterceptClick#intercept(Object, View, int)}
     *
     * @param clazz 默认主ViewHolder
     * @param ids   id = 0||不设置 id  --> 点击事件绑定到最外层 ItemView
     */
    public <T extends BaseViewHolder> void addOnItemClickListener(Class<T> clazz,
                                                                  OnItemClickListener clickListener,
                                                                  int... ids) {
        if (clazz != null && clickListener != null) {
            if (clicks.containsKey(clazz)) {
                OnClickMaker clickMaker = clicks.get(clazz);
                clickMaker.addClickListener(clickListener);
                clickMaker.addIds(ids);
                clicks.put(clazz, clickMaker);
            } else {
                clicks.put(clazz, new OnClickMaker(clickListener, ids));
            }
        }
    }

    private int emptyLayout = R.layout.item_empty;

    public void setEmpty(int item_empty) {
        this.emptyLayout = item_empty;
        this.NEED_EMPTY_SHOW = true;
    }

    //true-单选且选中之后不再取消,只能更换选中
    private boolean nonDiss = false;

    /**
     * @param tag 0-不需要 1-单选 2-多选 3-单选且选中之后不再取消,只能更换选中
     */
    public void setSelectTag(int tag) {
        if (tag == 0) {
            selectRule = null;
        } else if (tag == 1 || tag == 3) {
            nonDiss = tag == 3;
            selectRule = -1;
        } else {
            selectRule = new HashSet<Integer>();
        }
        if (tag != 0) {
            addOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(BaseAdapter adapter, BaseViewHolder holder, Object view, View v, int position) {
                    setSelect(adapter, holder, view, holder.itemView, position);
                }
            });
        }
    }

    Object selectRule;

    public boolean isSelect(int position) {
        if (selectRule != null) {
            if (selectRule instanceof Integer) {
                return (int) selectRule == position;
            } else {
                return ((HashSet<Integer>) selectRule).contains(position);
            }
        }
        return false;
    }

    public int getSelectInt() {
        if (selectRule instanceof Integer) {
            return (int) selectRule;
        }
        return -1;
    }

    public HashSet<Integer> getSelectSet() {
        if (selectRule instanceof HashSet) {
            return (HashSet<Integer>) selectRule;
        } else {
            return new HashSet<>();
        }
    }

    private int maxSize = Integer.MAX_VALUE;
    public static final int ACTION_SELECTED_NUM_TOO_MUSH = 0x098651;

    /**
     * @param size >0
     *             if selected is larger than size,will cal ActionPasser#onAction(ACTION_SELECTED_NUM_TOO_MUSH,nul)
     *             {@link ActionPasser#onAction(int, Object)}
     */
    public final void setMaxSelect(int size) {
        if (size <= 0) {
            //LOG.e("BaseAdapter", "setMaxSelect.设置参数必须为正整数");
            return;
        }
        this.maxSize = size;
    }

    public void setSelect(int position) {
        setSelect(null, null, null, null, position);
    }

    private void setSelect(BaseAdapter adapter, BaseViewHolder holder, Object o, View view, int position) {
        boolean isAdd = false;
        if (selectRule instanceof Integer) {
            if ((int) selectRule == position) {
                //LOG.e("BaseAdapter", "setSelect.862:" + position);
                if (mOnItemCheckListener != null) {
                    mOnItemCheckListener.onChange(getDataItem(position), false);
                }
                if (!nonDiss) {
                    selectRule = -1;
                }
            } else {
                //LOG.e("BaseAdapter", "setSelect.865:" + position);
                if (mOnItemCheckListener != null && ((int) selectRule) != -1) {
                    mOnItemCheckListener.onChange(getDataItem(((int) selectRule)), false);
                }
                selectRule = position;
                if (mOnItemCheckListener != null) {
                    mOnItemCheckListener.onChange(getDataItem(position), true);
                }
                isAdd = (int) selectRule != 3;
            }
            notifyChange();
        } else if (selectRule instanceof HashSet) {
            HashSet<Integer> selects = (HashSet<Integer>) selectRule;
            if (selects.contains(position)) {
                selects.remove(position);
                if (mOnItemCheckListener != null) {
                    mOnItemCheckListener.onChange(getDataItem(position), false);
                }
            } else {
                if (selects.size() >= maxSize) {
                    if (mActionPasser != null) {
                        mActionPasser.onAction(ACTION_SELECTED_NUM_TOO_MUSH, null);
                    }
                    return;
                }
                selects.add(position);
                isAdd = true;
                if (mOnItemCheckListener != null) {
                    mOnItemCheckListener.onChange(getDataItem(position), true);
                }
            }
            notifyItemChanged(position);
        } else {
            return;
        }
        if (adapter != null) {
            onItemCheckChange(adapter, holder, o, view, position, isAdd);
        }
    }

    protected void onItemCheckChange(BaseAdapter adapter, BaseViewHolder holder, Object o, View view, int position, boolean isAdd) {
        //LOG.e("BaseAdapter", isAdd + ".onItemCheckChange.929:" + position);
        // TODO: 2025/3/5 检测线面这一行的必要
        holder.itemView.setSelected(holder.getAbsoluteAdapterPosition() == position);
    }

    public void moveItem(int fromPosition, int toPosition) {
        Collections.swap(showData, fromPosition, toPosition);
        notifyItemMoved(fromPosition, toPosition);
    }

    public <T> void remove(T focusItem) {
        try {
            showData.remove(focusItem);
            notifyChange();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 需要实时刷新到ViewHolder的内容
     *
     * @param smoothX
     * @param width
     */
    public void notifyAction(int smoothX, int width) {

    }

    public void attachView(RecyclerView view) {
        this.recyclerView = view;
    }

    public interface OnItemCheckListener {

        /**
         * @param dataItem 对应数据
         * @param b        是否增加为选中
         */
        void onChange(Object dataItem, boolean b);
    }

    private OnItemCheckListener mOnItemCheckListener;

    public void setOnItemCheckListener(OnItemCheckListener listener) {
        this.mOnItemCheckListener = listener;
    }

    public interface DisplayOption<DATA> {
        /**
         * @param bean     需要判断的数据
         * @param rule     提供的判断条件
         * @param position
         * @return 是否显示该数据
         */
        boolean show(DATA bean, @NonNull Object rule, int position);
    }

    private DisplayOption mDisplayOption;
    private Object showRule;

    public void setDisplay(DisplayOption mDisplayOption) {
        this.mDisplayOption = mDisplayOption;
    }

    List<DATA> originData = new ArrayList<>();

    boolean display(Object rule, List data) {
        if (data != null) {
            this.originData.clear();
            this.originData.addAll(data);
        }
        return display(rule);
    }

    /**
     * you must used {@link #setDisplay(DisplayOption)} before display
     *
     * @return 是否刷新视图
     */
    public boolean display(Object rule) {
        final int showSize = showData.size();
        final int originSize = originData.size();
        if (mDisplayOption == null) {
            //LOG.e("BaseAdapter", "display error:you must used setDisplay before display");
            return false;
        }
        showRule = rule;
        if (rule == null) {
            if (originData.size() > showData.size()) {
                setData(deepCopy(originData));
                originData.clear();
                this.notifyChange();
                return true;
            }
            return false;
        }
        if (showSize > originSize) {
            originData.clear();
            originData.addAll(showData);
        }
        boolean hasChange = false;
        List<DATA> newShow = new ArrayList<>();
        for (int position = 0; position < originData.size(); position++) {
            if (mDisplayOption.show(originData.get(position), rule, position)) {
                newShow.add(originData.get(position));
                hasChange = true;
            }
        }
        this.showEmpty = emptyLayout() != 0 && (newShow.size() == 0);
        this.showData.clear();
        this.showData = newShow;
        if (usingDiffUtil) {

        } else {
            this.notifyChange();
        }
        return hasChange;
    }

    public static List deepCopy(List src) {
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(src);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in = new ObjectInputStream(byteIn);
            @SuppressWarnings("unchecked") List dest = (List) in.readObject();
            return dest;
        } catch (NotSerializableException e) {
            LOG.e("BEAN", "deepCopy.NotSerializableException");
            e.printStackTrace();
            return new ArrayList<>();
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    public static <E> E deepCopy(E src) {
        try {
            ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
            ObjectOutputStream out = new ObjectOutputStream(byteOut);
            out.writeObject(src);

            ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
            ObjectInputStream in = new ObjectInputStream(byteIn);
            @SuppressWarnings("unchecked") E dest = (E) in.readObject();
            return dest;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * ##########################################################################
     * RecyclerView 快速滑动时 EditText 等视图内容会随着视图复用而造成数据多余
     * Holder.class 实现 OnContentKeeper 即可解决此问题
     * ##########################################################################
     */

    public void setCash(VH holder) {//存储数据
        if (((OnContentKeeper) holder).getSaveViewId() == null || ((OnContentKeeper) holder)
                .getSaveViewId().length == 0) {
            return;
        }
        for (int saveContentId : ((OnContentKeeper) holder).getSaveViewId()) {
            Object save = ((OnContentKeeper) holder).getSave(saveContentId);
            if (save != null) {
                contentCash.put(holder.getPosition() + "" + saveContentId, save);
                //LOG.e("BaseAdapter", holder.getPosition() + " setCash: " + save);
            }
        }
    }

    public void useCash(VH holder) {//使用存储数据填充视图
        if (((OnContentKeeper) holder).getSaveViewId() == null || ((OnContentKeeper) holder)
                .getSaveViewId().length == 0) {
            return;
        }
        for (int saveContentId : ((OnContentKeeper) holder).getSaveViewId()) {
            Object value = contentCash.get(holder.getPosition() + "" + saveContentId);
            ((OnContentKeeper) holder).onRelease(value, saveContentId);
        }
    }

    //  public interface OnAttachedToBottomListener {
    //    void onAttachedToTop();
    //
    //    /**
    //     * @param attachBTop true - 最后一个 ViewHolder 顶部刚刚出现,实际不可见
    //     *                   false 最后一个 ViewHolder 完全可见
    //     *                   true -> false 过程中不回调
    //     */
    //    void onAttachedToBottom(boolean attachBTop);
    //  }
}
